<?php
/**
 * 简单的语言包功能
 *
 * 推荐的翻译KEY命名方式：<sub_category>:<key>
 * 例如，msg分类中进行子分类为controller和action两类，则词典内容可能为：
 * controller:create_ok
 * action:call_fail
 * 调用的时候则是：
 * msg.controller:create_ok
 * msg.action:call_fail
 *
 * 使用方法：
 * Com::glob()->t->setLocale('zh_CN.UTF-8') //切换语言包，一般情况下用得不多
 * Com::glob()->t['game.grid']  //读出语言包分类game（文件是zh_CN.UTF-8/game.php）里键值为grid的字符串
 * Com::glob()->t['dream'] //如果刚才已经设置了分类为game，则直接读取该分类内的dream字串
 * Com::glob()->t[array('msg.error', array($username))] //将$username变量内容代入某一翻译字串中返回
 *
 * @author ananda
 * @version 1.0
 */
class Translation extends Component implements ArrayAccess
{
    /**
     * 当前所使用的语言包
     * @var <string>
     */
    public $locale;

    /**
     * 设置语言包基础目录
     * @var <string>
     */
    public $base_dir = 'locale';

    /**
     * 当前分类名
     * @var <string>
     */
    public $category;

    /**
     * 语言包存储变量
     * @var <array>
     */
    protected $data = array();

    /**
     * 翻译时传递进来要替换翻译内容的参数
     * @var <array>
     */
    protected $params = null;

    public function init() {
        $this->base_dir = CROOT.$this->base_dir;
    }

    /**
     * ArrayAccess接口
     * @param <string> $offset
     * @return <boolean>
     */
    public function offsetExists($offset)
    {
        $key = $this->parseOffset($offset);
        $this->loadPackage($this->category);
        return isset($this->data[$this->locale][$this->category][$key]);
    }

    /**
     * ArrayAccess接口
     * @param <string> $offset
     * @return <string>
     */
    public function offsetGet($offset)
    {
        $key = $this->parseOffset($offset);
        $this->loadPackage($this->category);
        if ($this->params) {
            $result = vsprintf($this->data[$this->locale][$this->category][$key], $this->params);
            $this->params = null;
        } else {
            $result = $this->data[$this->locale][$this->category][$key];
        }
        return $result;
    }

    /**
     * ArrayAccess接口
     * @param <string> $offset
     * @param <string> $value
     */
    public function offsetSet($offset, $value)
    {
        $key = $this->parseOffset($offset);
        $this->loadPackage($this->category);
        $this->data[$this->locale][$this->category][$key] = $value;
    }

    /**
     * ArrayAccess接口
     * @param <string> $offset
     */
    public function offsetUnset($offset)
    {
        $key = $this->parseOffset($offset);
        $this->loadPackage($this->category);
        unset($this->data[$this->locale][$this->category][$key]);
    }

    /**
     * 设置语言包
     * @param <string> $locale
     */
    public function setLocale($locale)
    {
        $this->locale = $locale;
    }

    /**
     * 解析传进来的翻译地址
     * @param <string> $offset
     * @return <string>
     */
    public function parseOffset($offset)
    {
        if (is_array($offset)) {
            $this->params = $offset[1];
            $offset = $offset[0];
        }

        $pos = strpos($offset, '.');
        if ($pos) {
            $this->category = substr($offset, 0, $pos);
            $key = substr($offset, $pos + 1);
        } else {
            $key = $offset;
        }
        return $key;
    }

    /**
     * 获取某一语言包内某一分类的文件路径
     * @param <string> $locale
     * @param <string> $category
     * @return <string>
     */
    public function getPath($locale, $category)
    {
        return $this->base_dir.DIRECTORY_SEPARATOR.$locale.DIRECTORY_SEPARATOR."$category.php";
    }

    /**
     * 将语言包地入内存
     * @param <string> $category
     * @param <string> $locale
     */
    public function loadPackage($category, $locale = null)
    {
        //获取语言类型
        !$locale && ($locale = $this->locale);

        if (!isset($this->data[$locale][$category])) {
            $this->data[$locale][$category] = require $this->getPath($locale, $category);
        }
    }
}
